package SingleMode;

/**
 * @author 23737
 * @time 2021.9.9
 * 懒汉式单例————用的时候再去加载 DCL
 */
public class LazyMan {

    //构造器私有
    private LazyMan(){

    }

    //这里加上volatile关键字的作用是避免cpu指令重排
    private static volatile LazyMan lazyMan;

    //这是简单的懒汉式单例，但是是有问题的，单线程可以使用，但是多线程并发就会出问题
//    private static LazyMan getInstance(){
//        if (lazyMan == null) {
//            lazyMan = new LazyMan();
//        }
//        return lazyMan;
//    }

    //基于多线程的懒汉式单例,进行加锁操作，可以看到加了两层锁，这就是双重检测锁模式的懒汉式单例，简称DCL懒汉式
    public static LazyMan getInstance(){
        if (lazyMan == null) {
            synchronized (LazyMan.class){
                if (lazyMan == null) {
                    lazyMan = new LazyMan();   //不是一个原子性操作
                    /*
                    1.分配内存空间；
                    2.执行构造方法，初始化对象；
                    3.把这个对象指向内存空间。

                    ！！！但是cpu会进行指令重排，所以可能会执行132
                    所以为了避免指令重排，在lazyMan中加上volatile关键字，避免指令重排
                     */
                }
            }
        }
        return lazyMan;
    }


    /*
    但是DCL懒汉式也并不是安全的，可以用java中的反射机制来破坏单例
     */

}
